Efficient memory management is important for efficient execution of computer programs. Some environments leave the memory management to the programs, allowing programs to request and release memory as needed. Such programs are error-prone since they typically dependent on the programmer to manually determine the request and release of memory. In some garbage-collected environments, garbage collectors automatically release memory occupied by objects that are no longer in use, thereby improving the reliability of the programs' memory management.
FIG. 1 is a diagram illustrating the memory allocation of processes operating in a garbage-collected environment. In this example, system 120 assigns memory to processes such as 100-106 when the processes are initialized. In the example shown, the memory assigned to process 100 includes a committed section 110 and headroom 112. The committed section provides memory required to run the process. The amount of memory assigned to the committed section is represented as x. To achieve efficient collection of dead objects, garbage collection algorithms generally require a significant quantity of memory (“headroom”) beyond what is needed to contain the set of live objects. The headroom provides free memory to the process. Over time, some of the objects allocated in the headroom may be no longer used by the process. The garbage collector eventually frees these obsolete objects to make more free memory available. The headroom is typically assigned more memory than the committed section. In this example, the amount of memory assigned to the headroom is 5 times the amount of committed memory, denoted as 5×.
While the memory management method described above is useful for garbage-collected environments, several problems remain. Since the amount of headroom assigned to each process is typically determined before the process is launched, the process occupies the same amount of memory whether it is busy or idle. On a system with many running processes, there may be a few processes that utilize a significant portion of their headroom, while the majority of the processes stay idle and much of the free memory in their headroom remains unused. Thus, the memory in the system is not efficiently utilized. Also, systems implementing such a memory management scheme tend not to have good resiliency. If the memory demand of a process exceeds what is allocated (for example, due to unpredicted high peak demand or memory leaks), the process may crash. Additionally, such systems may have unpredictable behavior. For example, in some systems, other operations of the system are paused when the garbage collector is performing garbage collection. The pausing behavior is unpredictable and undesirable. In some systems, a concurrent garbage collector is used to ameliorate the pausing problem. However, when the rate of garbage generation is high, or when collection heuristics fail, the concurrent garbage collector still may be unable to prevent the system from pausing.
It would be desirable to implement memory management while avoiding pauses due to garbage collecting and offering better predictability. It would also be desirable to provide better resiliency and increase memory efficiency.